home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / alpha.arc / ALLOC.C < prev    next >
C/C++ Source or Header  |  1988-07-24  |  6KB  |  274 lines

  1. #include <stdio.h>
  2. #include "alloc.h"
  3. /* memory allocation routines
  4.  *
  5.  * Adapted from alloc routine in K&R; memory statistics and interrupt
  6.  * protection added for use with net package.
  7.  */
  8.  
  9. static HEADER base, *allocp = NULLHDR;
  10. static unsigned memfail;
  11.  
  12. /* Define ALLOCDEBUG for allocation recording. Note: works only with
  13.  * small memory model
  14.  */
  15. #ifdef    ALLOCDEBUG
  16. #define    NALLOC    150
  17. /* Map of allocated memory chunks */
  18. struct alloc {
  19.     char *addr;
  20.     unsigned size;
  21.     long pc;
  22. };
  23. struct alloc alloc[NALLOC];
  24. #endif
  25.  
  26. /* Allocate block of 'nb' bytes */
  27. char *
  28. malloc(nb)
  29. unsigned nb;
  30. {
  31.     HEADER *morecore();
  32.     register HEADER *p, *q;
  33.     register unsigned nu;
  34.     char i_state;
  35.  
  36. #ifdef    ALLOCDEBUG
  37.     struct alloc *ap;
  38.     unsigned short *ptr;
  39. #endif
  40.  
  41.     i_state = disable();
  42.     nu = ((nb + 3) >> 2) + 1;    /* Round up to full block, incl hdr */
  43.     if ((q = allocp) == NULLHDR){
  44.         base.s.ptr = allocp = q = &base;
  45.         base.s.size = 1;
  46.     }
  47.     for (p = q->s.ptr; ; q = p, p = p->s.ptr){
  48.         if (p->s.size >= nu){
  49.             /* This chunk is at least as large as we need */
  50.             if (p->s.size == nu){
  51.                 /* Perfect fit; remove from list */
  52.                 q->s.ptr = p->s.ptr;
  53.             } else {
  54.                 /* Carve out piece from end of entry */
  55.                 p->s.size -= nu;
  56.                 p += p->s.size;
  57.                 p->s.size = nu;
  58.             }
  59.             allocp = q;
  60.             p->s.ptr = p;    /* for auditing */
  61. #ifdef    ALLOCDEBUG
  62.             for(ap = alloc;ap < &alloc[NALLOC];ap++){
  63.                 if(ap->addr == NULLCHAR){
  64.                     ap->addr = (char *)(p+1);
  65.                     ap->size = nb;
  66.                     ptr = &nb;
  67. #ifdef    LARGECODE
  68.                     ap->pc = (long)ptr[-1] << 16 +
  69.                         (long)ptr[-2];
  70. #else
  71.                     ap->pc = (long)ptr[-1];
  72. #endif
  73.                     break;
  74.                 }
  75.             }
  76. #endif
  77.             restore(i_state);
  78.             return (char *)(p + 1);
  79.         }
  80.         if (p == allocp && (p = morecore(nu)) == NULLHDR){
  81.             memfail++;
  82.             restore(i_state);
  83.             return NULLCHAR;
  84.         }
  85.     }
  86. }
  87. /* Get more memory from the system and put it on the heap */
  88. HEADER *
  89. morecore(nu)
  90. unsigned nu;
  91. {
  92.     char *sbrk();
  93.     register char *cp;
  94.     register HEADER *up;
  95.  
  96.     if ((int)(cp = sbrk(nu << 2)) == -1)
  97.         return NULLHDR;
  98.     up = (HEADER *)cp;
  99.     up->s.size = nu;
  100.     up->s.ptr = up;    /* satisfy audit */
  101.     free((char *)(up + 1));
  102.     return allocp;
  103. }
  104. /* Grab as much memory as possible from the system and put it on the heap */
  105. unsigned
  106. grabcore()
  107. {
  108.     char *sbrk(),*cp;
  109.     register HEADER *up;
  110.     register unsigned int size;
  111.  
  112.     /* Initialize the heap pointers */
  113.     if (allocp == NULLHDR){
  114.         base.s.ptr = allocp = &base;
  115.         base.s.size = 1;
  116.     }
  117.     /* Find out where the break is */
  118.     cp = sbrk(0);
  119.     /* Now try to push it as high as possible */
  120.     for(size=256;;size += 256){
  121.         if(brk(cp + size) == -1)
  122.             break;
  123.     }
  124.     up = (HEADER *)cp;
  125.     up->s.size = size / sizeof(HEADER);
  126.     up->s.ptr = up;    /* satisfy audit */
  127.     free((char *)(up + 1));
  128.     return size;
  129. }
  130.  
  131. /* Put memory block back on heap */
  132. free(blk)
  133. char *blk;
  134. {
  135.     register HEADER *p, *q;
  136.     unsigned short *ptr;
  137.     char i_state;
  138. #ifdef    ALLOCDEBUG
  139.     struct alloc *ap;
  140. #endif
  141.  
  142.     i_state = disable();
  143. #ifdef    ALLOCDEBUG
  144.     for(ap = alloc;ap < &alloc[NALLOC];ap++){
  145.         if(ap->addr == blk){
  146.             ap->addr = NULLCHAR;
  147.             break;
  148.         }
  149.     }
  150. #endif
  151.     p = (HEADER *)blk - 1;
  152.     /* Audit check */
  153.     if(p->s.ptr != p){
  154.         ptr = (unsigned short *)&blk;
  155.         printf("WARNING!! freeing garbage (0x%x) pc = 0x%x %x\n",blk,
  156.             ptr[-1],ptr[-2]);
  157.         fflush(stdout);
  158.         restore(i_state);
  159. #ifdef    Z80
  160.         printf("SP = 0x%x\n",getsp());
  161.         for(;;) ;
  162. #else
  163.         return;
  164. #endif
  165.     }
  166.     /* Search the free list looking for the right place to insert */
  167.     for(q = allocp; !(p > q && p < q->s.ptr); q = q->s.ptr){
  168.         /* Highest address on circular list? */
  169.         if(q >= q->s.ptr && (p > q || p < q->s.ptr))
  170.             break;
  171.     }
  172.     if(p + p->s.size == q->s.ptr){
  173.         /* Combine with front of this entry */
  174.         p->s.size += q->s.ptr->s.size;
  175.         p->s.ptr = q->s.ptr->s.ptr;
  176.     } else {
  177.         /* Link to front of this entry */
  178.         p->s.ptr = q->s.ptr;
  179.     }
  180.     if(q + q->s.size == p){
  181.         /* Combine with end of this entry */
  182.         q->s.size += p->s.size;
  183.         q->s.ptr = p->s.ptr;
  184.     } else {
  185.         /* Link to end of this entry */
  186.         q->s.ptr = p;
  187.     }
  188.     allocp = q;
  189.     restore(i_state);
  190. }
  191.  
  192. #ifdef    notdef
  193. /* Move existing block to new area */
  194. char *
  195. realloc(area,size)
  196. char *area;
  197. unsigned size;
  198. {
  199.     unsigned osize;
  200.     HEADER *hp;
  201.     char *cp;
  202.     char i_state;
  203.  
  204.     hp = ((HEADER *)area) - 1;
  205.     osize = (hp->s.size -1) << 2;
  206.  
  207.     /* Make sure nobody else comes in and takes it */
  208.     i_state = disable();
  209.     free(area);
  210.     if((cp = malloc(size)) != NULLCHAR && cp != area)
  211.         memcpy((char *)cp,(char *)area,size>osize? osize : size);
  212.     restore(i_state);
  213.     return cp;
  214. }
  215. #endif
  216. /* Allocate block of cleared memory */
  217. char *
  218. calloc(nelem,size)
  219. unsigned nelem;    /* Number of elements */
  220. unsigned size;    /* Size of each element */
  221. {
  222.     register unsigned i;
  223.     register char *cp;
  224. #ifdef    ALLOCDEBUG
  225.     struct alloc *ap;
  226.     short *ptr;
  227. #endif
  228.     i = nelem * size;
  229.     if((cp = malloc(i)) != NULLCHAR)
  230.         memset(cp,0,i);
  231. #ifdef    ALLOCDEBUG
  232.     if(cp == NULLCHAR)
  233.         return cp;
  234.     /* Adjust caller field to indicate real caller, not calloc() */
  235.     ptr = (short *)&nelem;
  236.     for(ap = alloc; ap < &alloc[NALLOC];ap++)
  237.         if(ap->addr == cp)
  238.             ap->pc = (long)ptr[-1];
  239. #endif
  240.     return cp;
  241. }
  242. /* Print free list map */
  243. memstat()
  244. {
  245.     HEADER *p;
  246.     unsigned total;
  247.  
  248.     printf("malloc fails %u\n",memfail);
  249.     total = 0;
  250.     p = &base;
  251.     do {
  252.         total += p->s.size * sizeof(HEADER);
  253.         printf("0x%x %u",(unsigned)p,p->s.size * sizeof(HEADER));
  254.         if(p == allocp)
  255.             printf(" <-- allocp\n");
  256.         else
  257.             printf("\n");
  258.         p = p->s.ptr;
  259.     } while(p != &base);
  260.     printf("Total: %u bytes\n",total);
  261. #ifdef    ALLOCDEBUG
  262.     {
  263.         struct alloc *ap;
  264.         printf("addr      size      caller\n");
  265.         for(ap = alloc;ap < &alloc[NALLOC];ap++){
  266.             if(ap->addr != NULLCHAR)
  267.                 printf("0x%-8x%-10d%-10lx\n",ap->addr,
  268.                     ap->size,ap->pc);
  269.         }
  270.     }
  271. #endif
  272.     fflush(stdout);
  273. }
  274.